﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Moq;
using System.Web.Mvc;
using System.Security.Principal;
using System.Web;
using System.Collections.Specialized;
using System.Web.Routing;
namespace SchoolManagerMVC.Tests.Helpers
{
    public static class UserForTesting
    {
        public static void SetFakeControllerContext(this Controller controller, IPrincipal principal = null)
        {
            var httpContext = FakeHttpContext(principal);
            ControllerContext context = new ControllerContext(new RequestContext(httpContext, new RouteData()), controller);
            controller.ControllerContext = context;
            controller.Url = new UrlHelper(context.RequestContext, new RouteCollection());
        }

        public static HttpContextBase FakeHttpContext(IPrincipal principal = null) 
        { 
            var context = new Mock<HttpContextBase>(); 
            var files = new Mock<HttpFileCollectionBase>(); 
            var request = new Mock<HttpRequestBase>(); 
            var response = new Mock<HttpResponseBase>(); 
            var session = new Mock<HttpSessionStateBase>(); 
            var server = new Mock<HttpServerUtilityBase>(); 
            var user = new Mock<IPrincipal>(); 
            var identity = new Mock<IIdentity>(); 
            request.Setup(req => req.ApplicationPath).Returns("~/"); 
            request.Setup(req => req.AppRelativeCurrentExecutionFilePath).Returns("~/"); 
            request.Setup(req => req.PathInfo).Returns(string.Empty); 
            request.Setup(req => req.Form).Returns(new NameValueCollection()); 
            request.Setup(req => req.QueryString).Returns(new NameValueCollection()); 
            request.Setup(req => req.Files).Returns(files.Object); 
            response.Setup(res => res.ApplyAppPathModifier(It.IsAny<string>())).Returns((string virtualPath) => virtualPath); 
            user.Setup(usr => usr.Identity).Returns(identity.Object); 
            identity.SetupGet(ident => ident.IsAuthenticated).Returns(true); 
            context.Setup(ctx => ctx.Request).Returns(request.Object); 
            context.Setup(ctx => ctx.Response).Returns(response.Object); 
            context.Setup(ctx => ctx.Session).Returns(session.Object); 
            context.Setup(ctx => ctx.Server).Returns(server.Object); 
            context.Setup(ctx => ctx.User).Returns(user.Object); 

            if (principal != null)
                context.Setup(ctx => ctx.User).Returns(principal);

            return context.Object;
        }
    }

    public class MockPrincipal : IPrincipal
    {
        private IIdentity _identity;
        private readonly string[] _roles;

        public MockPrincipal(IIdentity identity, string[] roles)
        {
            _identity = identity;
            _roles = roles;
        }

        public IIdentity Identity
        {
            get { return _identity; }
            set { this._identity = value; }
        }

        public bool IsInRole(string role)
        {
            if (_roles == null)
                return false;
            return _roles.Contains(role);
        }
    }

    public class MockIdentity : IIdentity
    {
        private readonly string _name;

        public MockIdentity(string userName)
        {
            _name = userName;
        }

        public string AuthenticationType
        {
            get { throw new System.NotImplementedException(); }
        }

        public bool IsAuthenticated
        {
            get { return !String.IsNullOrEmpty(_name); }
        }

        public string Name
        {
            get { return _name; }
        }
    }
}
